iT邦幫忙

2022 iThome 鐵人賽

DAY 3
0
自我挑戰組

多人連線遊戲背後的原理與實作系列 第 20

Day20 - 程式實作(UDP非同步處理篇)

  • 分享至 

  • xImage
  •  

UDP Client 的非同步方法需用到 BeginReceive & EndReceive,而客戶端則是使用 BeginReceive,兩者皆是使用 IAsyncResult(AsyncCallBack)委派來處理不同執行序中非同步作業的結果。

在Server端

/// <summary>Receives incoming UDP data.</summary>
private static void UDPReceiveCallback(IAsyncResult _result)
{
    try
    {
        IPEndPoint _clientEndPoint = new IPEndPoint(IPAddress.Any, 0);
        byte[] _data = udpListener.EndReceive(_result, ref _clientEndPoint);
        udpListener.BeginReceive(UDPReceiveCallback, null);
        if (_data.Length < 4)
        {
            return;
        }
        using (Packet _packet = new Packet(_data))
        {
            int _clientId = _packet.ReadInt();
            if (_clientId == 0)
            {
                return;
            }
            if (clients[_clientId].udp.endPoint == null)
            {
                // If this is a new connection
                clients[_clientId].udp.Connect(_clientEndPoint);
                return;
            }
            if (clients[_clientId].udp.endPoint.ToString() == _clientEndPoint.ToString())
            {
                clients[_clientId].udp.HandleData(_packet);
            }
        }
    }
    catch (Exception _ex)
    {
        Debug.Log($"Error receiving UDP data: {_ex}");
    }
}

在Client端

/// <summary>Receives incoming UDP data.</summary>
private void ReceiveCallback(IAsyncResult _result)
{
    try
    {
        byte[] _data = socket.EndReceive(_result, ref endPoint);
        socket.BeginReceive(ReceiveCallback, null);
        if (_data.Length < 4)
        {
            instance.Disconnect();
            return;
        }
        HandleData(_data);
    }
    catch
    {
        Disconnect();
    }
}

上一篇
Day19 - 程式實作(UDP篇)
下一篇
Day21 - 程式實作(寄送封包篇一)
系列文
多人連線遊戲背後的原理與實作30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言